import React, { useCallback, useRef, forwardRef, useImperativeHandle, useState } from 'react';
import { Button, Card, Form, Icon, Input, PageHeader, Radio, Select, Upload } from 'antd';
import { FormComponentProps } from 'antd/es/form/Form';
import { ArticleType } from '@/domains/article';
import settings from '@/settings';
import Markdown, { MarkdownProps } from '@/components/Markdown';
import Richtext, { RichtextProps } from '@/components/Richtext';
import styles from './index.less';

const { Option, OptGroup } = Select;

const { tags } = settings;

const statusLayout: { left: [number, number]; both: [number, number]; right: [number, number] } = {
  left: [24, 0],
  both: [12, 12],
  right: [0, 24],
};

interface EditorProps extends FormComponentProps {
  onSave: (res: ArticleType) => void;
}

const Editor = Form.create<EditorProps>({ name: 'editor' })(
  forwardRef<FormComponentProps, EditorProps>(({ form, onSave }, ref) => {
    const markdown = useRef({} as MarkdownProps);
    const richtext = useRef({} as RichtextProps);
    const [isMarkdown, setIsMarkdown] = useState(true);
    const [markdownStatus, setMarkdownStatus] = useState(statusLayout.both);

    useImperativeHandle(ref, () => ({ form }));

    const handleUpload = useCallback(file => {
      const reader = new FileReader();
      reader.readAsText(file, 'UTF-8');
      reader.onload = (evt: any) => {
        try {
          const article: ArticleType = JSON.parse(evt.target.result);
          const { title, summary, contents } = article;
          if (title && summary && article.tags) {
            form.setFieldsValue({ title, summary, tags: article.tags });
          }
          if (contents) {
            setIsMarkdown(article.isMarkdown);
            setTimeout(
              () => (article.isMarkdown ? markdown : richtext).current.setContents(contents),
              0,
            );
          }
        } catch (e) {
          console.log(e);
        }
      };
      return false;
    }, []);

    const handleSave = useCallback(() => {
      form.validateFields((err, values) => {
        if (!err) {
          const contents = (isMarkdown ? markdown : richtext).current.getContents();
          onSave({ ...values, contents, isMarkdown });
        }
      });
    }, [isMarkdown]);

    const handleReset = useCallback(() => {
      form.resetFields();
      (isMarkdown ? markdown : richtext).current.setContents('');
    }, [isMarkdown]);

    return (
      <Card>
        <PageHeader
          className={styles.editorHeader}
          title={
            isMarkdown ? (
              <>
                <Icon type="file-markdown" />
                &nbsp;Markdown&nbsp;模式
              </>
            ) : (
              <>
                <Icon type="file-text" />
                &nbsp;Richtext&nbsp;模式
              </>
            )
          }
          extra={[
            <Button key="retweet" onClick={() => setIsMarkdown(!isMarkdown)}>
              <Icon type="retweet" />
              切换
            </Button>,
            <Button key="redo" onClick={handleReset}>
              <Icon type="redo" />
              重置
            </Button>,
            <Upload
              key="edit"
              className={styles.uploadBtn}
              beforeUpload={handleUpload}
              fileList={[]}
            >
              <Button>
                <Icon type="edit" />
                修改
              </Button>
            </Upload>,
            <Button key="save" onClick={handleSave}>
              <Icon type="save" />
              保存
            </Button>,
          ]}
        />
        <div style={{ display: 'flex' }}>
          <Form.Item style={{ flex: 1 }}>
            {form.getFieldDecorator('title', {
              rules: [{ required: true, message: '请输入笔记标题' }],
            })(<Input placeholder="请输入笔记标题" />)}
          </Form.Item>
          <Form.Item style={{ flex: 1, paddingLeft: 16 }}>
            {form.getFieldDecorator('tags', {
              rules: [{ required: true, message: '请选择笔记标签' }],
            })(
              <Select mode="tags" placeholder="请选择笔记标签" style={{ width: '100%' }}>
                {tags.map(tag => (
                  <OptGroup key={tag.value} label={tag.label}>
                    {tag.children.map(t => (
                      <Option key={t.value} value={t.value}>
                        {t.label}
                      </Option>
                    ))}
                  </OptGroup>
                ))}
              </Select>,
            )}
          </Form.Item>
        </div>
        <Form.Item>
          {form.getFieldDecorator('summary', {
            rules: [{ required: true, message: '请输入笔记摘要' }],
          })(<Input.TextArea autoSize={{ minRows: 3, maxRows: 3 }} placeholder="请输入笔记摘要" />)}
        </Form.Item>
        {isMarkdown ? (
          <div className={styles.markdownWrap} key="markdown">
            <div className={styles.statusControl}>
              <Radio.Group value={markdownStatus} onChange={e => setMarkdownStatus(e.target.value)}>
                <Radio.Button value={statusLayout.left}>
                  <Icon type="form" />
                  专注
                </Radio.Button>
                <Radio.Button value={statusLayout.both}>
                  <Icon type="read" />
                  实时
                </Radio.Button>
                <Radio.Button value={statusLayout.right}>
                  <Icon type="eye" />
                  预览
                </Radio.Button>
              </Radio.Group>
            </div>
            <Markdown ref={markdown} status={markdownStatus} />
          </div>
        ) : (
          <div className={styles.richtextWrap} key="richtext">
            <Richtext ref={richtext} />
          </div>
        )}
      </Card>
    );
  }),
);

export default Editor;
